home *** CD-ROM | disk | FTP | other *** search
- /*
- File: ShimSerialStub.c
-
- Contains: Routines used to install, remove and run the ".In" and ".Out" serial driver
- routines for the PC Card Modem ndrv ".Wabbit".
-
- Version: xxx put version here xxx
-
- Copyright: © 1996-1998 by Apple Computer, Inc., all rights reserved.
-
-
- */
-
- #define PBVERSION1 1
-
- #include <LowMem.h>
- #include <NameRegistry.h>
- #include <TextUtils.h>
- #include <stdio.h>
- #include <String.h>
- #include <Traps.h>
-
- #include "ShimSerialStub.h"
- #include "ShimSerialInternal.h"
-
- #define _DriverInstall 0xA43D
- #define _DriverRemove 0xA03E
-
- #define DebugMessage(x) SysDebugStr(x)
- // #define DebugMessage(x)
-
- #ifndef TraceMessage
- #define TraceMessage(i,x) { static local_enable = i; if (local_enable) USBExpertStatus(0, x, 0); local_enable = local_enable; }
- //#define TraceMessage(i,x) { static local_enable = i; if (local_enable) SysDebugStr(x); local_enable = local_enable; }
- #endif
-
- /* Incorporate debugging strings */
- #define noteError(s) sprintf((char*)context->errorString,"%s",s);
-
- //
- // Create the ".In" and ".Out" driver header structures. While the PC Card
- // Manager requires an 'ndrv' to be attached to the card node in the Name
- // Registry, the current model for the Serial Driver requires a ".In" and
- // ".Out" DRVR. In order to work around the conflicting models,we use the
- // ndrv to install these driver headers in the Unit Table for the Serial
- // Driver's use.
- //
- EJFDRVRHeader slotIn = {
- (1 << dReadEnable | 1 << dCtlEnable | 1 << dStatEnable | 1 << dNeedLock) << 8,
- 0,
- 0,
- 0,
- 32 + 0 * sizeof(RoutineDescriptor),
- 32 + 1 * sizeof(RoutineDescriptor),
- 32 + 2 * sizeof(RoutineDescriptor),
- 32 + 3 * sizeof(RoutineDescriptor),
- 32 + 4 * sizeof(RoutineDescriptor),
- "\p.slotIn",
-
- BUILD_ROUTINE_DESCRIPTOR(uppDriverProcInfo, &ShimSerialStubOpen),
- BUILD_ROUTINE_DESCRIPTOR(uppDriverProcInfo, &ShimSerialStubPrime),
- BUILD_ROUTINE_DESCRIPTOR(uppDriverProcInfo, &ShimSerialStubControl),
- BUILD_ROUTINE_DESCRIPTOR(uppDriverProcInfo, &ShimSerialStubStatus),
- BUILD_ROUTINE_DESCRIPTOR(uppDriverProcInfo, &ShimSerialStubClose)
- };
-
-
- EJFDRVRHeader slotOut = {
- (1 << dWritEnable | 1 << dCtlEnable | 1 << dStatEnable | 1 << dNeedLock) << 8,
- 0,
- 0,
- 0,
- 32 + 0 * sizeof(RoutineDescriptor),
- 32 + 1 * sizeof(RoutineDescriptor),
- 32 + 2 * sizeof(RoutineDescriptor),
- 32 + 3 * sizeof(RoutineDescriptor),
- 32 + 4 * sizeof(RoutineDescriptor),
- "\p.slotOut",
-
- BUILD_ROUTINE_DESCRIPTOR(uppDriverProcInfo, &ShimSerialStubOpen),
- BUILD_ROUTINE_DESCRIPTOR(uppDriverProcInfo, &ShimSerialStubPrime),
- BUILD_ROUTINE_DESCRIPTOR(uppDriverProcInfo, &ShimSerialStubControl),
- BUILD_ROUTINE_DESCRIPTOR(uppDriverProcInfo, &ShimSerialStubStatus),
- BUILD_ROUTINE_DESCRIPTOR(uppDriverProcInfo, &ShimSerialStubClose)
- };
-
-
-
-
- //
- // Statically define the Icon & Icon Mask for
- // the CRM structures. In the new world we
- // don't have resources so we have to do it
- // the hard way.
- //
- UInt32 CRMDeviceIcon[] = {
- 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x07FFFFFF, 0x78000001,
- 0x80780001, 0x804C0021, 0x804E0041, 0x80420081,
- 0x80420101, 0x80420201, 0x80FF0401, 0x88818801,
- 0x98819001, 0xB8FF2001, 0x98004C01, 0x88009A01,
- 0x80011601, 0x80021401, 0x80040A01, 0x80080561,
- 0x801002D1, 0x80200131, 0x804000E1, 0x80000001,
- 0x78000001, 0x07FFFFFF, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x07FFFFFF, 0x7FFFFFFF,
- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
- 0x7FFFFFFF, 0x07FFFFFF, 0x00000000, 0x00000000
- };
-
-
- /***********************************************************************************/
- // Function: InstallDriverControlEntries()
- // Description: This routine installs the ".In" and ".Out" entries in the Unit
- // Table.
- //
- // Input: Nothing
- // Output: Results
- /***********************************************************************************/
-
- OSErr InstallDriverControlEntries()
- {
- DriverRefNum refNum;
-
- TraceMessage(0,"\pEntering InstallDriverControlEntries");
-
- // Create and install input driver stub
- GetUniqueDrvrName(slotIn.drvrName,kDrvrInName);
- refNum = GetUniqueRefNum();
- if (refNum == 0)
- goto bail;
-
- if (noErr != CallInstallDriverProc((UniversalProcPtr)GetOSTrapAddress(_DriverInstall),
- (DRVRHeaderPtr)&slotIn,
- refNum))
- {
- DebugMessage("\pCouldn't install input driver stub");
- goto bail;
- }
-
- // Save input driver info
- gGlobals->drvrIn = &slotIn;
- gGlobals->refNumIn = refNum;
- gGlobals->dceIn = GetDCtlEntry(refNum);
-
- // Copy input driver info to it's dce
- (**(gGlobals->dceIn)).dCtlFlags = slotIn.drvrCtlFlags;
- (**(gGlobals->dceIn)).dCtlDriver = (Ptr)&slotIn;
-
-
- // Create and install output driver stub
- GetUniqueDrvrName(slotOut.drvrName,kDrvrOutName);
- refNum = GetUniqueRefNum();
- if (refNum == 0)
- goto bail;
-
- if (noErr != CallInstallDriverProc( (UniversalProcPtr)GetOSTrapAddress(_DriverInstall),
- (DRVRHeaderPtr)&slotOut,
- refNum))
- {
- DebugMessage("\pCouldn't install input driver stub");
- goto bail;
- }
-
- // Save output driver info
- gGlobals->drvrOut = &slotOut;
- gGlobals->refNumOut = refNum;
- gGlobals->dceOut = GetDCtlEntry(refNum);
-
- // Copy output driver info to it's dce
- (**(gGlobals->dceOut)).dCtlFlags = slotOut.drvrCtlFlags;
- (**(gGlobals->dceOut)).dCtlDriver = (Ptr)&slotOut;
-
-
- if (noErr != InstallCRM())
- {
- DebugMessage("\pCouldn't install CRM");
- goto bail;
- }
-
- return noErr;
-
- bail:
- return openErr; //••• use openErr for now but need to replace it
- }
-
-
-
-
-
- /***********************************************************************************/
- // Function: UniqueDrvrName()
- // Description: This returns true if the name parameter is unique in the unit table
- //
- // Input: name
- // Output: true if name is unique, otherwise false
- /***********************************************************************************/
-
- Boolean UniqueDrvrName(StringPtr name)
- {
- Ptr curUTableBase;
- short curUTableEntries;
- short refNum, unitNum;
- DCtlHandle dceHandle;
-
-
- TraceMessage(0,"\pEntering UniqueDrvrName");
-
- curUTableEntries = *(short*)0x01D2;
- curUTableBase = LMGetUTableBase();
-
- for (unitNum = 1; unitNum < curUTableEntries; unitNum++)
- {
- refNum = ~unitNum;
- if ((dceHandle = GetDCtlEntry(refNum)) != NULL){
- if (!PStrCmp(name, ((DRVRHeaderPtr)(*dceHandle)->dCtlDriver)->drvrName))
- return(false);
- }
- }
- return(true);
- }
-
-
-
-
-
- /***********************************************************************************/
- // Function: GetUniqueDrvrName()
- // Description: This routine builds a unique driver name based on the physical
- // slot of the card and the device number of the function.
- //
- // Input: Drive base name
- // Output: Driver name.
- /***********************************************************************************/
-
- void GetUniqueDrvrName(StringPtr name,StringPtr base)
- {
- TraceMessage(0,"\pEntering GetUniqueDrvrName");
-
- BlockMoveData(base,name,1 + base[0]);
-
- // check if this name is in use, if so then append a number and check again.
- // continue until a unique name is found.
- if (!UniqueDrvrName(name)){
- name[0]++;
- name[name[0]] = '0';
- }
- // check again, and keep incrementing the value
- while (!UniqueDrvrName(name)){
- name[name[0]]++;
- }
-
- }
-
-
-
-
-
- /***********************************************************************************/
- // Function: GetUniqueRefNum()
- // Description: This routine finds an unused driver reference number in the Unit
- // Table.
- //
- // Input: Nothing
- // Output: Driver reference number. 0=the table is full.
- /***********************************************************************************/
-
- short GetUniqueRefNum(void)
- {
- Ptr curUTableBase, newUTableBase;
- short curUTableEntries, newUTableEntries;
- short refNum, unitNum;
-
- TraceMessage(0,"\pEntering GetUniqueRefNum");
-
- curUTableEntries = *(short*)0x01D2;
- curUTableBase = LMGetUTableBase();
-
- for (unitNum = curUTableEntries-1;unitNum >= 48;unitNum--)
- {
- refNum = ~unitNum;
- if (GetDCtlEntry(refNum) == NULL)
- return refNum;
- }
-
- newUTableEntries = curUTableEntries + 32;
- newUTableBase = NewPtrSysClear((long)newUTableEntries * sizeof(Handle));
- if (newUTableBase == NULL)
- return 0; /* can't find/make an open slot */
-
- BlockMoveData(curUTableBase,newUTableBase,(long)curUTableEntries * sizeof(Handle));
- LMSetUTableBase(newUTableBase);
- *(short*)0x01D2 = newUTableEntries;
-
- unitNum = newUTableEntries - 1;
- refNum = ~unitNum;
- return refNum;
- }
-
-
-
-
-
- /***********************************************************************************/
- // Function: InstallCRM()
- // Description: Installs our device in the Communications Resource Manager's
- // queue.
- //
- // Input: Nothing
- // Output: Result
- /***********************************************************************************/
-
- OSErr InstallCRM(void)
- {
- CRMRecPtr crm;
- CRMSerialPtr crmser;
- Str255 name;
-
- TraceMessage(0,"\pEntering InstallCRM");
-
- crm = NULL;
- crmser = NULL;
-
-
- // Allocate the necessary CRM structures
- crm = (CRMRecPtr)NewPtrSysClear( sizeof(CRMRec));
- if (crm == NULL)
- goto label_error;
-
- crmser = (CRMSerialPtr)NewPtrSysClear(sizeof(CRMSerialRecord));
- if (crmser == NULL)
- goto label_error;
-
- // Save copies in our socket descriptor
- gGlobals->crm = crm;
- gGlobals->crmser = crmser;
-
- // Fill in crm fields...
- crm->qType = crmType;
- crm->crmDeviceType = crmSerialDevice;
- crm->crmDeviceID = 0;
- crm->crmAttributes = (UInt32) crmser;
- crm->crmStatus = 0;
- crm->crmRefCon = 'usbd';
-
- // Fill in crmser fields...
- crmser->version = curCRMSerRecVers;
-
- // Fill in the .in / .out driver names
- crmser->inputDriverName = NewString(gGlobals->drvrIn->drvrName);
- if (!crmser->inputDriverName)
- goto label_error;
- HLock((Handle) gGlobals->drvrIn->drvrName);
-
- crmser->outputDriverName = NewString(gGlobals->drvrOut->drvrName);
- if (!crmser->outputDriverName)
- goto label_error;
- HLock((Handle) gGlobals->drvrOut->drvrName);
-
- // Fill in the card name, icon, etc...
- GetUniqueCRMPortName(name);
- crmser->name = NewString(name);
- crmser->deviceIcon = (CRMIconRecord**)NewHandleSysClear(sizeof(CRMIconRecord));
- if (!crmser->deviceIcon)
- goto label_error;
- BlockMoveData(&CRMDeviceIcon[0],&crmser->deviceIcon[0]->oldIcon[0],128);
- BlockMoveData(&CRMDeviceIcon[32],&crmser->deviceIcon[0]->oldMask[0],128);
-
- crmser->ratedSpeed = kMaxBaudRate;
- crmser->maxSpeed = kMaxBaudRate;
- crmser->reserved = 0;
-
- // Install with CRM
- CRMInstall((CRMRecPtr)crm);
- return noErr;
-
-
- label_error:
- if (crmser != NULL)
- {
- if (crmser->inputDriverName != NULL)
- DisposeHandle((Handle)crmser->inputDriverName);
- if (crmser->outputDriverName != NULL)
- DisposeHandle((Handle)crmser->outputDriverName);
- if (crmser->deviceIcon != NULL)
- DisposeHandle((Handle)crmser->deviceIcon);
- DisposePtr((Ptr)crmser);
- }
-
- if (crm != NULL)
- DisposePtr((Ptr)crm);
-
- return openErr;
- }
-
-
-
-
-
- /***********************************************************************************/
- // Function: GetUniqueCRMPortName()
- // Description: This routine builds a unique port name based on the physical
- // slot of the card and the device number of the function.
- //
- // Input: Nothing
- // Output: Driver name.
- /***********************************************************************************/
-
- void GetUniqueCRMPortName(StringPtr name)
- {
- CRMRec theCRMRec,*theCRMRecPtr;
- CRMSerialPtr serialRecPtr;
- UInt32 iteration;
-
-
- TraceMessage(0,"\pEntering GetUniqueCRMPortName");
-
- // Set good default
- PStrCopy(name,"\pUSB Serial Adapter");
-
- // can we get the real product name from the name registry?
-
- theCRMRec.crmDeviceType = crmSerialDevice;
- theCRMRec.crmDeviceID = 0;
- theCRMRecPtr = &theCRMRec;
- iteration = 2;
-
- while(theCRMRecPtr != NULL)
- {
- theCRMRecPtr = CRMSearch(theCRMRecPtr);
- if (theCRMRecPtr != NULL)
- {
- serialRecPtr = (CRMSerialPtr)theCRMRecPtr->crmAttributes;
- if (!PStrCmp(*serialRecPtr->name,name))
- {
- if (iteration == 2)
- {
- name[0] += 2;
- if (name[0] > 31)
- name[0] = 31;
- }
-
- name[name[0] - 1] = ' ';
- name[name[0]] = '0' + (UInt8)iteration;
-
- theCRMRecPtr = &theCRMRec;
- iteration += 1;
- }
- }
- }
- }
-
-
-
-
-
- /***********************************************************************************/
- // Function: RemoveDriverControlEntries()
- // Description: This routine removes the ".In" and ".Out" entries in the Unit
- // Table.
- //
- // Input: Nothing
- // Output: Results
- /***********************************************************************************/
-
- OSErr RemoveDriverControlEntries(void)
- {
- OSErr err = noErr;
-
-
- TraceMessage(0,"\pEntering RemoveDriverControlEntries");
-
- // Remove our registration with the CRM
- RemoveCRM();
-
- // Remove the input driver from the Unit Table
- err = CallRemoveDriverProc((UniversalProcPtr) GetOSTrapAddress(_DriverRemove),
- gGlobals->refNumIn);
- if (err != noErr)
- DebugMessage("\pCouldn't remove the input driver.");
-
- // Remove the output driver from the Unit Table
- err = CallRemoveDriverProc((UniversalProcPtr) GetOSTrapAddress(_DriverRemove),
- gGlobals->refNumOut);
- if (err != noErr)
- DebugMessage("\pCouldn't remove the output driver.");
-
- return err;
- }
-
-
-
-
-
- /***********************************************************************************/
- // Function: RemoveCRM()
- // Description: Removes our device from the Communications Resource Manager's
- // queue.
- //
- // Input: Nothing
- // Output: Nothing
- /***********************************************************************************/
-
- void RemoveCRM(void)
- {
- TraceMessage(0,"\pEntering RemoveCRM");
-
- if (gGlobals->crm)
- {
- CRMRemove(gGlobals->crm);
-
- if (gGlobals->crmser)
- {
- DisposeHandle((Handle)gGlobals->crmser->inputDriverName);
- DisposeHandle((Handle)gGlobals->crmser->outputDriverName);
- DisposeHandle((Handle)gGlobals->crmser->deviceIcon);
- DisposePtr((Ptr)gGlobals->crmser);
- }
-
- DisposePtr((Ptr)gGlobals->crm);
- }
- }
-
-
-
-
-
- /***********************************************************************************/
- // Function: ShimSerialStubOpen()
- // Description: Opens the driver.
- //
- // Input: ParmBlkPtr, DCtlPtr
- // Output: Status
- /***********************************************************************************/
-
- OSErr ShimSerialStubOpen (ParmBlkPtr pb, DCtlPtr dce)
- {
- OSErr err = noErr; // assume success
-
- #pragma unused (dce)
-
- TraceMessage(0,"\pEntering ShimSerialStubOpen");
-
- // only do the open stuff once per driver pair
- if (gGlobals->openSession == false)
- err = (OSErr) DoOpenSession(pb);
-
- if ( err )
- err = openErr;
-
- pb->ioParam.ioResult = err;
-
- return err;
-
- } /* end of ShimSerialStubOpen() */
-
-
- /***********************************************************************************/
- // Function: ShimSerialStubClose()
- // Description: Closes the driver.
- //
- // Input: ParmBlkPtr, DCtlPtr
- // Output: Status
- /***********************************************************************************/
-
- OSErr ShimSerialStubClose (ParmBlkPtr pb, DCtlPtr dce)
- {
- OSErr err = noErr; // assume success
-
- TraceMessage(0,"\pEntering ShimSerialStubClose");
- #pragma unused (dce)
-
- // only do the close stuff once per driver pair
- if (gGlobals->openSession)
- err = (OSErr) DoCloseSession(pb);
-
-
- return err;
-
- } /* end of ShimSerialStubClose() */
-
-
- /***********************************************************************************/
- // Function: ShimSerialStubPrime()
- // Description: Handles reads and writes to and from the driver.
- //
- // Input: ParmBlkPtr, DCtlPtr
- // Output: Status
- /***********************************************************************************/
-
- OSErr ShimSerialStubPrime (ParmBlkPtr pb, DCtlPtr dce)
- {
- OSErr err = noErr; // assume success
-
- TraceMessage(0,"\pEntering ShimSerialStubPrime");
- // initialize actual count read
- pb->ioParam.ioActCount = 0;
-
- // make sure we've something to read or write
- //
- err = (OSErr)((pb->ioParam.ioReqCount) ? 1 : noErr);
- if ( err )
- {
-
- //
- // is this a read or write?
- //
-
- switch (pb->ioParam.ioTrap & 0x00FF)
- {
- case aRdCmd:
- TraceMessage(0,"\pPrime - Read!");
- if ( !gGlobals )
- {
- err = readErr;
- break;
- }
- err = B_Read(gGlobals, 0, (IOParam *)pb);
- if ( err > noErr )
- gGlobals->pbIn = pb;
- #ifdef OLDSTUFF
- // if we didn't find our globals, return readErr;
- if ( !gGlobals )
- {
- err = readErr;
- break;
- }
-
- // attempt to fill read request immediately
- // from any pending data in the input buffer
- err = B_FillReadRequest(gGlobals, (IOParam *) pb);
-
- // if read request unsatisfied and we have no uart (card
- // was physically removed, etc.) then we better bail out
- // now with a readErr rather than leave the client hanging
-
- // TODO: How do we check for a device that disappeared
- //if ( !gGlobals->uartRegs )
- //{
- // err = readErr;
- // break;
- //}
-
- // otherwise if the request didn't complete, we set
- // this request as our new current read pb
- if ( err > noErr )
- gGlobals->pbIn = pb;
-
- // if software or hardware flow control are in effect
- // we prime input mechanism according to buffer levels
- // (otherwise, input is enabled and the pb will be
- // treated as input characters arrive from the uart)
- B_InputFlowControl(gGlobals);
- #endif //OLDSTUFF
- break;
-
- case aWrCmd:
- // otherwise set this request as our current write pb
- gGlobals->pbOut = pb;
-
- err = B_Write(gGlobals, 0, (IOParam *)pb);
- #ifdef OLDSTUFF
- // if we didn't find our globals, return writErr;
- // -OR-
- // if we have no uart (card was physically removed, etc.)
- // then there's no use in trying, there won't be any transmit
- // buffer empty interrupts, so just return writErr now...
-
- // TODO: check for device that disappeared.
- if ((!gGlobals) /* || (!gGlobals->uartRegs) */)
- {
- err = writErr;
- break;
- }
-
- // otherwise set this request as our current write pb
- gGlobals->pbOut = pb;
-
- // turn on write buffer empty interrupts to prime our write mechanism
- B_EnableOutput(gGlobals);
- #endif //OLDSTUFF
-
- break;
- }
- }
-
- // call the IODone routine if err <= noErr
- if (err <= noErr)
- ShimSerialStubIODone(pb,dce,err);
-
- return err;
-
- } /* end of ShimSerialStubPrime() */
-
- /***********************************************************************************/
- // Function: ShimSerialStubControl()
- // Description: Handles control calls to the driver.
- //
- // Input: ParmBlkPtr, DCtlPtr
- // Output: Status
- /***********************************************************************************/
-
- OSErr ShimSerialStubControl (ParmBlkPtr pb, DCtlPtr dce)
- {
- UInt16 csCode;
- OSErr err = noErr; // assume success
-
- TraceMessage(0,"\pEntering ShimSerialStubControl");
-
- // if we didn't find our globals, return controlErr
- if (!gGlobals)
- return(controlErr);
-
- csCode = pb->cntrlParam.csCode;
-
- if (csCode == killCode)
- {
- //
- // the ioQueue should have already been dispensed with by
- // the device manager, so all we need to do is clear our
- // local pending io flags... nb: we behave _just like
- // the serial driver_ : a killIO on one driver is like a
- // killIO on both... read and write will both be flushed...
- // what bothers me about this is what if the client only
- // wanted to kill input _or_ output ? the device manager
- // doesn't know that the serial driver treats these calls
- // on both drivers... hmmmm... hope this works, but
- // i'm not convinced.
- //
- gGlobals->pbIn = nil;
- gGlobals->pbOut = nil;
-
- //
- // now turn off write buffer empty interrupts
- //
- B_EnableOutput(gGlobals);
-
- //
- // kill io is always immediate
- //
-
- err = noErr;
- }
- else
- {
- switch (csCode)
-
-
- {
- case goodbye:
- err = noErr;
- break;
-
- case kSERDConfiguration: /* program port speed, bits/char, parity, and stop bits */
- // config UInt16 passed as parameter
- err = B_SerReset(gGlobals, *(UInt16*) pb->cntrlParam.csParam);
- break;
-
-
- case kSERDInputBuffer: /* set buffer for chars received with no read pending */
- // buffer pointer and buffer length passed as parameters
- err = B_SetBuffer(gGlobals, *(Ptr*) pb->cntrlParam.csParam, *(UInt16*) (((Ptr) pb->cntrlParam.csParam) + 4));
- break;
-
-
- case kSERDSerHShake: /* equivalent to SerHShake, largely obsolete */
- case kSERDHandshake: /* superset of 10, honors setting of fDTR */
- // handshake record passed
- B_SetSerShk(gGlobals, (SerShk*) pb->cntrlParam.csParam, csCode);
- break;
-
-
- case kSERDClearBreak: /* assert break signal on output */
- case kSERDSetBreak: /* negate break state on output */
- B_SetBreak(gGlobals, (csCode == kSERDSetBreak));
- break;
-
-
- case kSERD115KBaud: /* set 115.2K baud data rate */
- (void) B_SetBaudRate(gGlobals, 115200);
- break;
-
- case kSERD230KBaud:
- err = controlErr;
- break;
-
-
- case kSERDBaudRate: /* set explicit baud rate, other settings unchanged */
- *(UInt16*) pb->cntrlParam.csParam = B_SetBaudRate(gGlobals, *(UInt16*) pb->cntrlParam.csParam);
- break;
-
-
- case kSERDAssertDTR: /* assert DTR output */
- case kSERDNegateDTR: /* negate DTR output */
- B_EnableDTR(gGlobals, (csCode == kSERDAssertDTR));
- break;
-
-
- case kSERDSetPEChar: /* select char to replace chars with invalid parity */
- case kSERDSetPEAltChar: /* select char to replace char that replaces chars with invalid parity */
- B_SetParErrChar( gGlobals,
- (csCode == kSERDSetPEAltChar),
- *(unsigned char*) pb->cntrlParam.csParam,
- *(((unsigned char*) pb->cntrlParam.csParam)+1));
- break;
-
-
- case kSERDSetXOffFlag: /* set XOff output flow control (same as receiving XOff) */
- case kSERDClearXOffFlag: /* clear XOff output flow control (same as receiving XOn) */
- gGlobals->serStat.xOffHold = (csCode == kSERDSetXOffFlag);
- B_EnableOutput(gGlobals);
- break;
-
-
- case kSERDSendXOn: /* send XOn if input flow control state is XOff */
- case kSERDSendXOnOut: /* send XOn regardless of input flow control state */
- B_SendXOn(gGlobals, (csCode == kSERDSendXOn));
- break;
-
-
- case kSERDSendXOff: /* send XOff if input flow control state is XOn */
- case kSERDSendXOffOut: /* send XOff regardless of input flow control state */
- B_SendXOff(gGlobals, (csCode == kSERDSendXOff));
- break;
-
- default:
- err = controlErr;
- break;
- }
-
- // call the IODone routine if err <= noErr
- if (err <= noErr)
- ShimSerialStubIODone(pb,dce,err);
- }
-
- return err;
-
- } /* end of ShimSerialStubControl() */
-
-
- /***********************************************************************************/
- // Function: ShimSerialStubStatus()
- // Description: Handles status calls to the driver.
- //
- // Input: ParmBlkPtr, DCtlPtr
- // Output: Status
- /***********************************************************************************/
-
- OSErr ShimSerialStubStatus(ParmBlkPtr pb,DCtlPtr dce)
- {
- OSErr err = noErr; // assume success
-
- TraceMessage(0,"\pEntering ShimSerialStubStatus");
-
- // if we didn't find our globals, return statusErr
- if (!gGlobals)
- return(statusErr);
-
-
- switch (pb->cntrlParam.csCode)
- {
- case kSERDInputCount: /* return characters available */
- *(UInt32*)(&pb->cntrlParam.csParam[0]) = B_SerGetBuf(gGlobals);
- break;
-
- case kSERDStatus: /* return SerStaRec record information */
- B_SerStatus(gGlobals, (SerStaRec*) pb->cntrlParam.csParam);
- break;
-
- case kSERDVersion: /* return version number in first byte of csParam */
- *(char *) pb->cntrlParam.csParam = 9; /* 9 implies that we do > 57.6K */
- break;
-
- default: /* Unknown csCode */
- err = statusErr;
- break;
- }
-
- // call the IODone routine if err <= noErr
- if (err <= noErr)
- ShimSerialStubIODone(pb,dce,err);
-
- return err;
- }
-
-
- /***********************************************************************************/
- // Function: ShimSerialStubIODone()
- // Description: Notifies the Device Manager that the I/O request has completed.
- //
- // Input: DCtlPtr, result
- // Output: Nothing
- /***********************************************************************************/
-
- void ShimSerialStubIODone(ParmBlkPtr pb,DCtlPtr dce,OSErr result)
- {
- TraceMessage(0,"\pEntering ShimSerialStubIODone");
-
- pb->ioParam.ioResult = result;
- if (!(pb->ioParam.ioTrap & (1 << noQueueBit)))
- CallIODoneProc( LMGetJIODone(), dce, result );
- }
-